home *** CD-ROM | disk | FTP | other *** search
- #include <Folders.h>
- #include <LowMem.h>
- #include "PStrings.h"
- #include "A4Code.h"
-
- pascal CIconHandle (*gOldGetCIcon)(short id);
- pascal PixPatHandle (*gOldGetPixPat)(short id);
- short gJGNEBusy;
- ProcPtr gRealJGNEFilter;
- long gLastSwitch;
- short gLastIndex;
-
- pascal CIconHandle GetCIconPatch(short id);
- pascal PixPatHandle GetPixPatPatch(short id);
- OSErr GetKScopeFolder(short *vRefNum, long *dirID, short *numFiles);
- OSErr OpenKScopeFile(short *fNum, Boolean useLast, Boolean *alreadyOpen);
-
- #define DELAY_TICKS 300
-
- /* -------------------------------------------------------------------------------- */
- static Boolean IsCapsLockDown(unsigned long *km)
- {
- unsigned char *km8 = (unsigned char *)km;
- unsigned short keycode;
- short ii, jj;
-
- for(ii = 0; ii < 16; ii++)
- if(km8[ii])
- for(jj = 0; jj < 8; jj++)
- if(km8[ii] & (1 << jj))
- {
- keycode = ii * 8 + jj;
- if(keycode == 0x39)
- return true;
- }
- return false;
- }
-
-
- /* -------------------------------------------------------------------------------- */
- OSErr GetKScopeFolder(short *vRefNum, long *dirID, short *numFiles)
- {
- OSErr err;
-
- if((err = FindFolder(kOnSystemDisk, kExtensionFolderType, false, vRefNum, dirID)) == noErr)
- {
- CInfoPBRec pb;
- Str255 str;
- static char schemeFolder[] = "\pKaleidoscope Color Schemes";
-
- BlockMoveData(schemeFolder, str, schemeFolder[0] + 1);
- pb.dirInfo.ioCompletion = NULL;
- pb.dirInfo.ioNamePtr = str;
- pb.dirInfo.ioVRefNum = *vRefNum;
- pb.dirInfo.ioFDirIndex = 0;
- pb.dirInfo.ioDrDirID = *dirID;
- if((err = PBGetCatInfoSync(&pb)) == noErr)
- {
- *numFiles = pb.dirInfo.ioDrNmFls;
- if(pb.hFileInfo.ioFlAttrib & 0x0010)
- *dirID = pb.dirInfo.ioDrDirID;
- else
- err = fnfErr;
- }
- }
- return err;
- }
-
- /* -------------------------------------------------------------------------------- */
- OSErr OpenKScopeFile(short *fNum, Boolean useLast, Boolean *alreadyOpen)
- {
- short vRefNum, numFiles;
- Str255 name;
- long dirID;
- OSErr err;
-
- if((err = GetKScopeFolder(&vRefNum, &dirID, &numFiles)) == noErr)
- {
- CInfoPBRec pb;
-
- if(!useLast)
- gLastIndex = ((long)Random() + 32767) * numFiles / 65536 + 1;
-
- pb.hFileInfo.ioCompletion = NULL;
- pb.hFileInfo.ioNamePtr = name;
- pb.hFileInfo.ioVRefNum = vRefNum;
- pb.hFileInfo.ioFDirIndex = gLastIndex;
- pb.hFileInfo.ioDirID = dirID;
- if((err = PBGetCatInfoSync(&pb)) == noErr &&
- !(pb.hFileInfo.ioFlAttrib & 0x0010))
- {
- *alreadyOpen = (pb.hFileInfo.ioFRefNum > 0);
- if((*fNum = HOpenResFile(vRefNum, dirID, name, fsRdPerm)) == -1)
- err = ResError();
- }
- else
- err = fnfErr;
-
- if(useLast)
- gLastIndex = ((long)Random() + 32767) * numFiles / 65536 + 1;
- }
- return err;
- }
-
- /* -------------------------------------------------------------------------------- */
- pascal CIconHandle GetCIconPatch(short id)
- {
- long oldA4;
- CIconHandle icon;
- OSErr err;
- Boolean alreadyOpen;
- short resFile;
- unsigned long keys[4];
- pascal CIconHandle (*realproc)(short id);
-
- oldA4 = SetUpA4();
- realproc = gOldGetCIcon;
- GetKeys(keys);
- if(!IsCapsLockDown(keys))
- err = OpenKScopeFile(&resFile, false, &alreadyOpen);
- else
- err = fnfErr;
- SetA4(oldA4);
-
- icon = realproc(id);
-
- if(!err)
- CloseResFile(resFile);
-
- return icon;
- }
-
- /* -------------------------------------------------------------------------------- */
- pascal PixPatHandle GetPixPatPatch(short id)
- {
- long oldA4;
- PixPatHandle pat;
- OSErr err;
- Boolean alreadyOpen;
- unsigned long keys[4];
- short resFile;
- pascal PixPatHandle (*realproc)(short id);
-
- oldA4 = SetUpA4();
- realproc = gOldGetPixPat;
- GetKeys(keys);
- if((id < -12288 || id > -12280) && !IsCapsLockDown(keys))
- err = OpenKScopeFile(&resFile, true, &alreadyOpen);
- else
- err = fnfErr;
- SetA4(oldA4);
-
- pat = realproc(id);
-
- if(!err)
- CloseResFile(resFile);
-
- return pat;
- }
-
- /* -------------------------------------------------------------------------------- */
- static short myGNE(EventRecord *evt, short preResult)
- {
- OSErr theErr;
-
- if(evt->what == nullEvent && LMGetTicks() > gLastSwitch + DELAY_TICKS)
- {
- long value;
-
- Gestalt('khac', &value);
- gLastSwitch = LMGetTicks();
- }
- return preResult;
- }
-
- /* -------------------------------------------------------------------------------- */
- static asm void JGNEPatch(void)
- {
- subq.l #4,A7 // make room on the stack for gRealJGNEFilter
- move.l A4,-(A7) // save old A4
- move.l A1,-(A7) // save the event pointer in case we mess it up
- move.l D0,-(A7) // save D0 because SetUpA4 uses it
- jsr SetUpA4 // point A1 at our A4
- move.l (A7)+,D0 // restore old D0
-
- tst.w gJGNEBusy // is this a reentrant call?
- bne busy
-
- move.w #1,gJGNEBusy // mark us as being busy
- movem.l A0/A2-A4/D1-D7,-(A7)// save everything just to be safe (JGNE uses D0 & A1)
- move.w D0,-(A7) // push pre-result
- move.l A1,-(A7) // push event record pointer
- jsr myGNE // do the real work
- addq.l #6,A7 // pop pre-result; post-result in D0
- movem.l (A7)+,A0/A2-A4/D1-D7// restore all the regs we (probably unnecessarily) saved
- move.w D0,16(A7) // stash result where caller expects it
- move.w #0,gJGNEBusy // we're not busy anymore
-
- busy:
- move.l gRealJGNEFilter,8(A7) // get previous jGNE
- move.l (A7)+,A1 // put the event pointer back
- move.l (A7)+,A4 // restore A4
- bne leave // rts to previous jGNE
- addq.l #4,A7 // clean up - previous jGNE was NULL
- leave:
- rts
- }
-
- /* =================================== Startup Code =============================== */
-
- #define OKICON 128
- #define DEADICON 129
-
- static void ShowInit(int ID)
- {
- Handle showInit;
- void (*ShowIcon)(short);
-
- if(showInit = GetResource('Code', -4048))
- {
- HLock(showInit);
- ShowIcon = (void (*)(short))StripAddress(*showInit);
- ShowIcon(ID);
- HUnlock(showInit);
- }
- }
-
- /* -------------------------------------------------------------------------------- */
- void main (void)
- {
- OSErr theErr;
- long oldA5;
- short prefFile;
- unsigned char theKeys[16];
-
- EnterCodeResource();
- RememberA4();
-
- ShowInit(OKICON);
-
- gJGNEBusy = 0;
- gLastIndex = 1;
- gLastSwitch = LMGetTicks();
-
- gOldGetCIcon = (pascal CIconHandle (*)(short))NGetTrapAddress(_GetCIcon, ToolTrap);
- NSetTrapAddress((UniversalProcPtr)GetCIconPatch, _GetCIcon, ToolTrap);
-
- gOldGetPixPat = (pascal PixPatHandle (*)(short))NGetTrapAddress(_GetPixPat, ToolTrap);
- NSetTrapAddress((UniversalProcPtr)GetPixPatPatch, _GetPixPat, ToolTrap);
-
- gRealJGNEFilter = (ProcPtr)LMGetGNEFilter();
- LMSetGNEFilter((GNEFilterUPP)JGNEPatch);
-
- DetachResource(GetResource('INIT', 0));
-
- ExitCodeResource();
- }